%\documentclass{article}
\documentclass[12pt,a4paper,utf8x]{article}
\usepackage [frenchb]{babel}

% Pour pouvoir utiliser
\usepackage{ucs}
\usepackage[utf8x]{inputenc}

\usepackage{graphicx}
\usepackage{soul}

\usepackage{url} % Pour avoir de belles url
\usepackage {geometry}

% Pour mettre du code source
\usepackage {listings}
% Pour pouvoir passer en paysage
\usepackage{lscape}

% Pour pouvoir faire plusieurs colonnes
\usepackage {multicol}

% Pour l'interligne de 1.5
\usepackage {setspace}
% Pour les marges de la page
\geometry{a4paper, top=2.5cm, bottom=3.5cm, left=2cm, right=2cm, marginparwidth=1.2cm}

%\parskip=5pt %% distance entre § (paragraphe)
\sloppy %% respecter toujours la marge de droite

% Pour les pénalités :
%\interfootnotelinepenalty=150 %note de bas de page
%\widowpenalty=150 %% veuves et orphelines
%\clubpenalty=150

%Pour la longueur de l'indentation des paragraphes
%\setlength{\parindent}{15mm}


\title{Rapport final - Implémentation du paradigme de programmation orienté acteurs}
\author{Guillaume Burel, Andra-Ioana Dragomir, Ouassim Karrakchou, \\Alexandre Vienne\\
INSA Lyon - département Télécommunications, Services et Usages\\
\{guillaume.burel, andra-ioana.dragomir, ouassim.karrakchou, \\alexandre.vienne\}@insa-lyon.fr}
\date{Juin 2012}
\begin{document}
\maketitle

\setlength{\columnsep}{1cm}
\begin{multicols}{2}

\section{Présentation}
Dans le cadre de la formation de Java, encadrée par Stéphane Frenot, nous avons été amenés à effectuer un travail liant défi technique et gestion de projet.

Le projet consistait en l'implémentation du paradigme de programmation orienté Acteurs, répondant à des problématiques de synchronisation et de parallélisation, dont les contraintes sont abordées plus en détail dans la fiche acteurs rendue précédemment.

Notre implémentation repose sur la notion de super-acteurs, composant essentiel du système, qui effectuent les opérations de création transparentes ou explicites d'acteurs, d'envoi de messages, de tolérance aux surcharges et de distribution. Aussi, nous proposons un acteur permettant à l'utilisateur de contrôler les acteurs à l'aide d'une interface disponible via telnet. Ainsi, la plupart des fonctionnalités et des objets sous-jacents sont abstraits.

L'utilisateur n'a donc que peu de contrôle sur le fonctionnement des différents mécanismes mis en place, le maximum de l'intelligence étant déportée vers le super-acteur et les classes composant la bibliothèque. Nous avons donc écrit une API très simple à prendre en main, à l'aide de laquelle pourront être créés rapidement et efficacement des programmes subissant les problématiques auxquelles notre implémentation prétend répondre.

Un exemple simple de traitement d'images est présent aux côtés de l'API. Il a été réalisé tel un Proof of Concept pour démontrer la facilité de conception d'une application utilisant notre implémentation, ainsi que sa modularité.

\section{Aperçu de l'API}


\subsection{Classe Acteur}

Tout acteur est défini par un comportement qui va spécifier les traitements qu'il va effectuer.
Pour cela, il doit hériter de la classe abstraite Acteur qui met en place deux threads : l'un prend en charge les routines de l'acteur et l'autre contrôle la file de messages.

Deux méthodes doivent cependant être redéfinies : standardRoutine() où doivent être spécifiés les traitements effectués avant la récupération des messages, et handleMessage() prend en charge les messages.

Elle doit également spécifier si la StandardRoutine() est utilisé pour adapter en conséquence la récupération des messages, passant du mode bloquant au mode non-bloquant. Cela permet à l'acteur d'agir dans le cas où il ne recevrait pas de message. Au contraire, en mode bloquant, le comportement de l'acteur s'apparente à un service pour lequel il ne fait que réagir à des évènements, tel un démon.

En cas d'exception menant à la terminaison d'un acteur, le super-acteur est informé de la défaillance afin de lui permettre de mettre à jour sa table interne, dans le cas où la transmission d'une telle information est possible.

\subsection{Classe SuperActor}

Comme souvent évoqué dans ce rapport, le super-acteur est indispensable au fonctionnement du système. C'est lui qui centralise l'intelligence de l'application et a pour tâche de veiller à son bon fonctionnement.

Il instancie par réflexibilité les acteurs lorsque cela est nécessaire pour la transmission du message - si l'acteur n'existe pas - ou si l'utilisateur le demande spécifiquement, auquel cas il est supprimé directement après traitement.

Aussi, il peut effectuer un choix dans la sélection de l'acteur à contacter lors de la réception d'un message ce qui lui offre la possibilité de répartir de manière optimale la charge sur les différents acteurs en fonction de leur état et des ressources localement disponibles. En effet, lorsqu'un acteur rencontre une difficulté à traiter les messages qu'il reçoit, il informe le super-acteur de son état qui met à jour sa liste des acteurs connus en fonction de leur comportement.

Le super-acteur est en outre capable de lier deux super-acteurs correspondant à deux systèmes différents pour permettre aux acteurs du premier système de communiquer avec les acteurs du second. Nous avons opté pour une démarche "push", où un super-acteur déclare à l'autre qu'il connaît un comportement et qu'il peut ainsi router les messages. Le premier peut alors mettre à jour sa table d'acteurs en associant le comportement indiqué avec l'adresse du second super-acteur.

Enfin, le super-acteur met à jour sa table lorsqu'il est informé de la terminaison d'un acteur. Le système est donc imperméable à la défaillance des acteurs sur lesquels il a autorité et entretient une liste consistante de ces derniers.

\subsection{Classe ListenSocket}

La classe ListenSocket compose la classe Acteur, prenant en charge les messages de manière asynchrone, via l'utilisation de sockets. Toutes les communications inter-acteurs, qu'elles soient locales ou distantes, transitent donc par ces sockets, aucune distinction n'étant faite entre les différents messages selon leur destination. Ce choix a été effectué dans l'optique d'un passage indolore à la distribution des acteurs sur un réseau local, voire sur l'Internet. Le passage des messages est donc indépendant de la localisation physique de l'acteur.

Aussi, c'est elle qui attribue les sockets aux différents acteurs en leur allouant un port d'écoute qui croît au fil des créations d'acteurs. Elle fournit aussi une socket de connexion à une adresse spécifiée pour l'envoi de messages.

La classe stocke les messages dans une LinkedBlockingQueue, structure flexible permettant leur récupération en mode bloquant ou inversement.

\subsection{Classe ActorAddress}

La classe ActorAddress est une composante essentielle de l'API acteur : c'est elle qui permet d'identifier les acteurs pour le passage de messages. C'est à l'aide de cette propriété que notre API autorise la distribution des acteurs sur le réseau. Elle contient l'IP et le port sur lesquels écoute l'acteur, facilitant les travaux de routage du super-acteur.

\subsection{Classe ActorAttributes}

C'est une classe métier utilisée par le super-acteur, lui permettant de maintenir une table des acteurs qu'il crée en stockant leur identifiant de file de messages (ActorAddress), leur référence et leur disponibilité.

Ainsi, lors de la surcharge d'un acteur, le super-acteur peut créer de nouveaux acteurs ayant le même comportement pour pallier la défaillance de l'acteur en question.

\subsection{Classe Message}

Les messages échangés par les acteurs sont constitués du comportement voulu, chaque acteur ne répondant qu'à un seul comportement par sa méthode de traitement, le contenu du message, qui doit être sérialisable. Le message contient de plus des informations sur les traitements en marge du comportement qui doivent être effectués respectivement par le destinataire, comme un ordre de terminaison, et par le super-acteur à qui pourrait être indiqué la volonté de créer un nouvel acteur à cet effet. Par défaut, le super-acteur consulte sa liste d'acteurs répartis selon leur comportement pour en sélectionner un adapté à la situation, selon sa localisation ou sa disponibilité, mais ce comportement peut être redéfini comme évoqué précédemment. 

Ainsi, le message dans son intégralité est sérialisable ce qui autorise sa transmission par socket. De plus, il est très extensible, la seule contrainte sur le contenu du message étant sa seriabilité.

\subsection{Classe Monitor}

La classe Monitor donne un accès direct au système à travers le port 2222, en donnant à l'utilisateur la possibilité de contrôler le système à l'aide de ce dernier, via l'envoi de messages en se faisant passer pour le super-acteur.

Ainsi, on peut terminer l'exécution du programme, envoyer des messages arbitraires aux différents acteurs ou faire le lien entre super-acteurs afin de mettre en place les fonctionnalités de distribution des acteurs.

\section{Exemple d'utilisation}

Pour illustrer notre travail, nous avons choisi de mettre en place un programme simple de traitement de l'image. Ce choix est judicieux car notre API de programmation est orientée vers le calcul parallèle, le domaine du traitement de l’image s’y prêtant parfaitement. 

Une chaîne de traitement est mise en place ; elle va effectuer les opérations s'imposant à la bonne prise en charge de l'image en entrée.

Un premier acteur est placé en entrée, tâchant d'ouvrir l'image associée au chemin qui lui est donné et la transmettre sous forme sérialisée - à l'aide de la classe SentImage - à un second acteur - CutterActor - qui, lui, la découpera. Aux différentes parties de l'image sont adjointes des informations nécessaires pour la bonne recomposition de l'image dans une phase ultérieure du traitement.

Ce dernier acteur transmet alors les parties ainsi créées à différents acteurs qui, eux, appliqueront un traitement spécifique à la partie qui leur est transmise, tels que NoirBlancActor, MirroirActor et BinarizeActor. Ces traitements s'effectuent parallèlement en spécifiant explicitement au super-acteur la nécessité de créer un nouvel acteur à cet effet.

Chacun des acteurs ayant pour charge une partie de l'image envoient alors cette dernière après traitement à l'acteur RecomposerActor qui réassemble les morceaux à l'aide des informations associées. L'image ainsi recomposée est jointe à l'acteur DisplayerActor qui l'affiche à l'aide de la bibliothèque Swing.

\end{multicols}
\end{document}

